#include "save-traces.h"

#include <iostream>
#include <string>
#include <fstream>
#include <iomanip>	// setprecision()
#include <ctime>	// time(); ctime()

const int float_precision = 9;

inline bool isnan(float x)
{
  return (x!=x);
}

save_traces::save_traces(unsigned length, float wav_start, float wav_stop, float sens, float res_bw, std::string &title)
{

  if (length <2)
    throw "Trace array must have at least two samples";

  //this->filename=filename;
  this->length = length;
  this->sensitivity = sens;
  this->resolution_bandwidth = res_bw;

// Get current time
  time_t rawtime;
  std::time ( &rawtime );

  struct tm * time_info = std::localtime ( &rawtime );
  std::strftime (this->date_time, 20, "%Y-%m-%dT%H:%M:%S", time_info);

// Prepare wavelength labels
/*
  float interval = (wav_stop - wav_start) / (length-1);
  if (interval <= 0)
    throw "Wavelength stop must be larger than wavelength start";

  this->x = new float[length];

// Fill up the x measurements
  float *px=x;
  for (unsigned i=0; i<length; i++,px++)
    *px = interval * i + wav_start;
*/

// Backup configurations to SQL database
sql_insert_description((std::string)date_time, title, wav_start, wav_stop,sensitivity, resolution_bandwidth,length);

}
/*
save_traces::~save_traces()
{
  delete[] x;

  for (std::vector<float*>::iterator pY=all_y.begin(); pY!=all_y.end(); pY++)
    delete[] *pY;
}
*/

void save_traces::input_trace(float new_z, float new_y[],unsigned length)
{
  if (length !=this->length)
    throw "Cannot save data (dimension mismatch)";

// Backup data to SQL database
float *trace = new_y;
sql_insert_trace(this->date_time, new_z, trace, length);

// Store data in heap
/*
  y = new float[length];

  float *py=y;
  for (unsigned i=0; i<length; i++,py++)
    *py=new_y[i];

  all_y.push_back(y);
*/
}
/*
void save_traces::input_z(float new_z)
{
  z.push_back(new_z);
}

void save_traces::print_vector_ascii(char varname[], unsigned length, float *px)
{
  traces_file_ascii << std::endl
  << "# name: " << varname <<"\n"
  << "# type: matrix\n"
  << "# rows: 1\n"
  << "# columns: " << length << '\n';
  for (unsigned i=0; i<length-1; i++,px++)
    traces_file_ascii << std::setprecision(float_precision) << *px << ' ';
  traces_file_ascii << std::setprecision(float_precision) << *px << std::endl;
}

void save_traces::print_vector_ascii(char varname[], std::vector<float> &vect)
{
  traces_file_ascii << std::endl
  << "# name: " << varname << "\n"
  << "# type: matrix\n"
  << "# rows: 1\n"
  << "# columns: " << vect.size() << '\n';
  for (unsigned i=0; i< vect.size()-1; i++)
    traces_file_ascii << std::setprecision(float_precision) << vect[i] << ' ';
  traces_file_ascii << std::setprecision(float_precision) << *(vect.rbegin()) << std::endl;
}

void save_traces::print_matrix_ascii(char varname[], unsigned nx, std::vector<float*> &matrix)
{
  traces_file_ascii << std::endl
  << "# name: " << varname << "\n"
  << "# type: matrix\n"
  << "# rows: " << matrix.size() << '\n'
  << "# columns: " << nx << '\n';
  for (std::vector<float*>::iterator pY=matrix.begin(); pY!=matrix.end(); pY++)
    {
      float *py = *pY;
      for (unsigned i=0; i< nx-1; i++,py++)
        {
          if (isnan(*py))
            traces_file_ascii << "NaN ";
          else
            traces_file_ascii << std::setprecision(float_precision) << *py << ' ';
        }
      if (isnan(*py))
        traces_file_ascii << "NaN ";
      else
        traces_file_ascii << std::setprecision(float_precision) << *py << std::endl;
    }
}

void save_traces::print_scalar_ascii(char varname[], float value)
{
  traces_file_ascii << std::endl
  << "# name: " << varname << "\n"
  << "# type: scalar\n"
  << value << std::endl;
}

void save_traces::print_string_ascii(char varname[], std::string value)
{
  traces_file_ascii << std::endl
  << "# name: " << varname << "\n"
  << "# type: string\n"
  << "# elements: 1\n"
  << "# length: " << value.length() << "\n"
  << value << std::endl;
}

void save_traces::write_to_file()
{
std::string filename2 = filename + ".txt";
  traces_file_ascii.open(filename2.c_str());

  if (!traces_file_ascii.is_open())
    throw "Could not save to file '" + filename + "'";

// Save start date and time
  traces_file_ascii << "## Date=" << date_time << std::endl << std::endl;

// Save wavelength configuration
  traces_file_ascii << "## Wavelength Start=" << x[0] << std::endl;
  traces_file_ascii << "## Wavelength Stop=" << x[length-1] << std::endl;

// Save date and time as variable
  print_string_ascii("date_acquired",(std::string) this->date_time);


// Save OSA Settings
  print_scalar_ascii("sensitivity",this->sensitivity);
  print_scalar_ascii("resolution_bandwidth",this->resolution_bandwidth);

// Save wavelengths
  print_vector_ascii("wavelength",this->length,x);

  if (z.size() != 0)
    {
// Save displacments
      print_vector_ascii("displacement",z);
    }
// Save reflection data
  print_matrix_ascii("reflection",length,all_y);

  traces_file_ascii.close();
}
*/
